#!/usr/bin/perl

# Internetwork Management Program-Tabbed Telenet/SSH client for internetwork management.
# Copyright (C) 2010 Matt O'Brien
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

use warnings;
use strict;
use Tk;
use Tk::NoteBook;
use podcore;
my $mw = MainWindow->new;
$mw->geometry ("800x600");
$mw->optionAdd("*font", "-*-arial-normal-r-*-*-*-120-*-*-*-*-*-*");
$mw->optionAdd("*borderWidth", 1);
$mw->title ("INMP");

my $mbar = $mw->Menu();
$mw->configure (-menu => $mbar);
my $file = $mbar->cascade (-label=>"File", -underline=>0, -tearoff=>0);
$file->command (-label=>"Connect", -underline=>0, -command=>\&connect);
$file->command (-label=>"Save", -underline=>0, -command=>\&save);
$file->command (-label=>"Restore", -underline=>0, -command=>\&restore);
$file->command (-label=>"Nuke", -underline=>0, -command=>\&nuke);
$file->command (-label=>"Initialize", -underline=>0, -command=>\&init);
$file->command (-label=>"Disconnect", -underline=>0, -command=>\&disconnect);
$file->command (-label=>"Exit", -underline=>0, -command=>sub {system ("killall xterm"); exit;});
my $canv = $mw->Canvas(-bg => 'lightsteelblue',
     -relief => 'sunken',
     -width => 800,
     -height => 600)->pack(-expand => 1, -fill => 'both');

my $xtermWidth = 400;
my $xtermHeight = 300;

my $height = 24;
my $width = 80;

my $book = $canv->NoteBook()->pack(-fill=>'both', -expand=>1);
my %info;

my %hosts;

MainLoop;

sub connect {
	my $top = $mw->Toplevel(-title=>"Connect");
	my $numLabel = $top->Label (-text=>"Enter pod number to connect to")->pack();
	my $numEntry = $top->Entry(-textvariable => \my $num)->pack();

	my $heightLabel = $top->Label (-text=>"Enter height in number of characters")->pack();
	my $heightEntry = $top->Entry(-textvariable => \$height)->pack();

	my $widthLabel = $top->Label (-text=>"Enter width in number of characters")->pack();
	my $widthEntry = $top->Entry(-textvariable => \$width)->pack();

	my $ok = $top->Button (-text => "OK", -command=>sub { return if !$num; $top->destroy(); connectHelp ($num); } )->pack(-side => 'left');
	$top->bind ('<Return>' => sub { return if !$num; $top->destroy(); connectHelp ($num); } );
	my $cancel = $top->Button (-text => "Cancel", -command=> [$top => 'destroy'])->pack(-side =>'right');
}
sub connectHelp {
	my $podnum = shift;
	my $host = sprintf ("128.213.10.%d", $podnum + 100);
	for my $port (sort keys %podcore::ports) { 
		my $tab = $book->add ("$podcore::ports{$port}", -label => $podcore::ports{$port});
		my $address = "$host $port";
		create ($address, $tab);
		$info{"$podcore::ports{$port}"} = "$host $port";
	}
	$book->raise("r1");
}

sub macro {
	my $file = shift;
	open my $fh, '<', $file or die $!;
	
	while (<$fh>) {
		chomp;
		my @line = split / /;
		$line[1] =~ s/:/ /, $line[1] if $line[1] =~ /:/;
		$hosts{$line[0]} = $line[1];
	}
	close $fh or die $!;

	while (my ($key, $value) = each %hosts) {
		my $tab = $book->add ("$hosts{$key}", -label => $hosts{$key});
		create ($value, $tab);
		$info{"$hosts{$key}"} = $value;
	}
}
	
sub create {
	my $host = shift;
	my $tab = shift;

	#Reset height and width to default if some
	#idiot sets them to 0 in the window.
	$height = 80 if !$height;
	$width = 24 if !$width;
	my $geometry = $width . "x" . $height;

	## this Frame is needed for including the xterm in Tk::Canvas 
	my $xtermContainer = $tab->Frame(-container=>1, -width => 700, -height=> 700)->pack (-expand=>0, -fill=>'both');
	my $xtid = $xtermContainer->id();
	# converting the id from HEX to decimal as xterm requires a decimal Id
	my ($xtId) = sprintf hex $xtid;

	system("xterm -sb -geometry $geometry -into $xtId -hold -e \'telnet $host; bash\' &");	
}
sub save {
	my $top = $mw->Toplevel(-title=>"Save");
	my $numLabel = $top->Label (-text=>"Enter pod number to save")->pack();
	my $numEntry = $top->Entry(-textvariable => \my $num)->pack();
	my $fileLabel = $top->Label (-text=>"Enter filename to save")->pack();
	my $fileEntry = $top->Entry(-textvariable => \my $fileName)->pack();

	my $ok = $top->Button (-text => "OK", -command=>sub { return if !$num || !$fileName; $top->destroy(); saveHelp ($num, $fileName); } )->pack(-side => 'left');
	$top->bind ('<Return>' => sub { return if !$num || !$fileName; $top->destroy(); saveHelp ($num, $fileName); } );
	my $cancel = $top->Button (-text => "Cancel", -command=> [$top => 'destroy'])->pack(-side =>'right');
}

sub saveHelp {
	my $podnum = shift;
	my $fileName = shift;
	my $flag = 0;
	open my $fh, '>', $fileName or die "Can not to open $fileName for writing: $!";
	foreach my $port (sort keys %podcore::ports) {
		my $device = $podcore::ports{$port}; #the device we are saving
		my @output = podcore::SaveConfig ($podnum, $port, $device);
		sleep (1);
		print $fh "----------BEGIN CONFIG FOR DEVICE $device----------\n";
		for my $line (@output) {
			if ($line =~ /interface (.*)/) {
				print $fh $line;
				print $fh " no shut\n";
			}
			else {
				print $fh $line;
			}
		}
		print $fh "----------END CONFIG FOR DEVICE $device----------\n\n";
	}
	close $fh or die $!;
	my $top = $mw->Toplevel();
	my $done = $top->Label (-text=>"Done Saving Configs")->pack();
	my $ok = $top->Button (-text=>"OK", -command=>sub { $top->destroy(); } )->pack();
	$top->bind ('<Return>' => sub { $top->destroy(); } );
}
sub restore {
	my $top = $mw->Toplevel(-title=>"Restore");
	my $numLabel = $top->Label (-text=>"Enter pod number to restore")->pack();
	my $numEntry = $top->Entry(-textvariable => \my $num)->pack();
	my $fileLabel = $top->Label (-text=>"Enter filename to restore from")->pack();
	my $fileEntry = $top->Entry(-textvariable => \my $fileName)->pack();

	my $ok = $top->Button (-text => "OK", -command=>sub { return if !$num || !$fileName; $top->destroy(); restoreHelp ($num, $fileName); } )->pack(-side => 'left');
	$top->bind ('<Return>' => sub { return if !$num || !$fileName; $top->destroy(); restoreHelp ($num, $fileName); } );
	my $cancel = $top->Button (-text => "Cancel", -command=> [$top => 'destroy'])->pack(-side =>'right');
}

sub restoreHelp {
	my $podnum = shift;
	my $fileName = shift;

	open my $fh, '<', $fileName or die $!;

	foreach my $port (sort keys %podcore::ports) {
		my $device = $podcore::ports{$port}; #the device we are loading 
			my @data;

		while (<$fh>) {
			chomp;
			if (/----------BEGIN CONFIG FOR DEVICE $device----------/) {
				next;
			}
			if (/Building configuration\.\.\./) {
				next;
			}
			if (/Current configuration.*/) {
				next;
			}
			if (/version.*/) {
				next;
			}
			if (/----------END CONFIG FOR DEVICE $device----------/) {
				last;
			} 
			if (!$_) {
				next;
			}
			if (/!/) {
				next;
			}
			push @data, $_;
		}
		podcore::Load ($podnum, $port, $device, @data);
	}
	close $fh or die "Can not close $file: $!";
	my $top = $mw->Toplevel(-title=>"Complete");
	my $done = $top->Label (-text=>"Done Saving Configs")->pack();
	my $ok = $top->Button (-text=>"OK", -command=>sub { $top->destroy(); } )->pack();
	$top->bind ('<Return>' => sub { $top->destroy(); } );
}
	
sub nuke {}

sub init {
	my $top = $mw->Toplevel(-title=>"Initialize");
	my $numLabel = $top->Label (-text=>"Enter pod number to initialize")->pack();
	my $numEntry = $top->Entry(-textvariable => \my $num)->pack();

	my $ok = $top->Button (-text => "OK", -command=>sub { return if !$num; $top->destroy(); initHelp ($num); } )->pack(-side => 'left');
	$top->bind ('<Return>' => sub { return if !$num; $top->destroy(); initHelp ($num); } );
	my $cancel = $top->Button (-text => "Cancel", -command=> [$top => 'destroy'])->pack(-side =>'right');
}

sub initHelp {
	my $podnum = shift;
	foreach my $port (sort keys %podcore::ports) {
		my $device = $podcore::ports{$port}; #the device we are saving
		podcore::Init ($podnum, $port, $device);
	}
	my $top = $mw->Toplevel(-title=>"Complete");
	my $done = $top->Label (-text=>"Done Restoring Configs")->pack();
	my $ok = $top->Button (-text=>"OK", -command=>sub { $top->destroy(); } )->pack();
	$top->bind ('<Return>' => sub { $top->destroy(); } );
}

sub disconnect {
	foreach my $port (sort keys %podcore::ports) {
		$book->delete("$podcore::ports{$port}");
	}
	system ("killall xterm");
}
